package excelanttasks;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * Interesting extension
 * - Add multi sheet support
 * 		- Each sheet should use the name of the sheet
 * 		- Default should be single sheet
 * - Allow to process XLSX files
 * 
 * @author Norbert Kopcsek
 */
public class ExcelToLocalesConverter {
	/**
	 * The path to the excel file.
	 * Default is "Locale.xls".
	 */
	public String excelPath = "Locale.xls";

	/**
	 * The path where to store the created property files.
	 * Default is "locale/".
	 */
	public String localePath = "locale/";

	/**
	 * The name of the created property file.
	 * Default is "Locale.properties".
	 */
	public String resourceName = "Locale.properties";

	/**
	 * The number of the header row. The header row contains the identifiers for the
	 * locales (en_US, de_DE and so on). Default is 2.
	 */
	public Integer headerRowNumber = 2;

	/**
	 * The number of the key column. The key column contains the keys used in
	 * Flex. Default is 1.
	 */
	public Integer keyColumnNumber = 1;
	
	/**
	 * The identifier of the key column.
	 * Default is "labelkey".
	 * TODO This should not be required since it's already know by keyColumnNumber 
	 */
	public String keyLabel = "labelkey";
	
	private Map<Integer, OutputStreamWriter> filesMap;
	private FileInputStream fileInputStream;
	private HSSFSheet excelSheet;
	
	public void convert() {

		filesMap = new HashMap<Integer, OutputStreamWriter>();

		try {
			getExcelSheet();
			setupWriters();
			writeRows();
			closeAllFiles();
		} catch (IOException e) {
			e.printStackTrace();
			
		}
	}
	
	
	protected void getExcelSheet() throws IOException {
		try {
			fileInputStream = new FileInputStream(excelPath);
	
			// load excel sheet
			// until now it is only single paged
			// TODO Add multipage support
			POIFSFileSystem poiFileSystem = new POIFSFileSystem(fileInputStream);
			HSSFWorkbook workbook = new HSSFWorkbook(poiFileSystem);
			excelSheet = workbook.getSheetAt(0);
			
		} catch (IOException e) {
			e.printStackTrace();
			
		}
	}
	protected void setupWriters() throws UnsupportedEncodingException, FileNotFoundException {
		HSSFRow headerRow = excelSheet.getRow(headerRowNumber - 1);

		new File("locale").mkdir();

		for (int i = headerRow.getFirstCellNum(); i < headerRow
				.getLastCellNum(); i++) {
			
			HSSFCell headerCell = headerRow.getCell(i);
			if (headerCell != null) {
				String label;
				if (!headerCell.getRichStringCellValue().getString().trim()
						.equals(keyLabel)) {
					label = headerCell.getRichStringCellValue().getString()
							.trim();
				} else {
					label = "debug";
				}

				// create folder for locale
				String path = localePath + label;
				new File(path).mkdir();

				// create file and fileoutputstream
				path += "/" + resourceName;
				
				OutputStreamWriter fileWriter = new OutputStreamWriter(
						new FileOutputStream(path), "UTF-8");
				filesMap.put(i, fileWriter);
			}
		}
	}
	protected void writeRows() {
		for (int r = headerRowNumber; r <= excelSheet.getLastRowNum(); r++) {
			writeRow(excelSheet.getRow(r));
		}
	}
	protected void writeRow(HSSFRow row) {
		if (getKeyOfRow(row) == null)
			return;

		Iterator<Integer> i = filesMap.keySet().iterator();
		while (i.hasNext()) {
			Integer nextColumn = i.next();
			OutputStreamWriter writer = filesMap.get(nextColumn);
			writeCell(row, nextColumn, writer);
		}
	}

	protected void writeCell(HSSFRow row, Integer column,
			OutputStreamWriter writer) {
		HSSFCell cell = row.getCell(column);

		if (cell != null
				&& !cell.getRichStringCellValue().getString().trim().equals("")) {
			try {
				if (!isDebugColumn(column))
					writer.append(getKeyOfRow(row) + "="
							+ cell.getRichStringCellValue().getString().trim()
							+ "\n");
				else
					writer.append(getKeyOfRow(row) + "={"
							+ cell.getRichStringCellValue().getString().trim()
							+ "}\n");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	protected Boolean isDebugColumn(Integer column) {
		return column == keyColumnNumber - 1;
	}

	protected String getKeyOfRow(HSSFRow row) {
		try {
			return row.getCell(keyColumnNumber - 1).getRichStringCellValue()
					.getString().trim();
		} catch (Exception e) {
			return null;
		}

	}

	protected void closeAllFiles() {
		Iterator<Integer> i = filesMap.keySet().iterator();
		while (i.hasNext()) {
			try {
				filesMap.get(i.next()).close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
